package cn.com.shopec.erp.warehouse.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import cn.com.shopec.erp.common.constant.SZSCMConstant;
import cn.com.shopec.erp.common.page.PageFinder;
import cn.com.shopec.erp.common.page.PageQuery;
import cn.com.shopec.erp.common.utils.DateUtil;
import cn.com.shopec.erp.common.utils.NoUtil;
import cn.com.shopec.erp.common.utils.StringUtil;
import cn.com.shopec.erp.stock.commo.ObjectUtil;
import cn.com.shopec.erp.system.common.UserUtils;
import cn.com.shopec.erp.warehouse.dao.IStockTransferDao;
import cn.com.shopec.erp.warehouse.dao.IStockTransferProductDao;
import cn.com.shopec.erp.warehouse.entity.StockTransfer;
import cn.com.shopec.erp.warehouse.entity.StockTransferProduct;
import cn.com.shopec.erp.warehouse.service.IStockTransferService;
import cn.com.shopec.erp.warehouse.vo.StockTransferVo;

@Service
public class StockTransferServiceImpl implements IStockTransferService {

	@Resource
	private IStockTransferDao stockTransferDao;

	@Resource
	private IStockTransferProductDao stockTransferProductDao;

	@Override
	public PageFinder<StockTransfer> queryStockTransferList(StockTransferVo stockTransfer, PageQuery pageQuery) {
		PageFinder<StockTransfer> poageFinder = stockTransferDao.pagedByCriteria(getQueryCriteria(stockTransfer),
				pageQuery.getPage(), pageQuery.getPageSize());
		return poageFinder;
	}

	@Override
	public PageFinder<StockTransferProduct> queryStockTransferProductList(StockTransferVo stockTransfer, PageQuery pageQuery) {
		PageFinder<StockTransferProduct> poageFinder = null;
		if (ObjectUtil.isNotNull(stockTransfer) && !StringUtil.isEmpty(stockTransfer.getTransferNo())) {
			DetachedCriteria detachedCriteria = stockTransferProductDao.createCriteria();
			detachedCriteria.add(Restrictions.eq("transferNo", stockTransfer.getTransferNo()));
			poageFinder = stockTransferProductDao.pagedByCriteria(detachedCriteria, pageQuery.getPage(),
					pageQuery.getPageSize());
		}
		return poageFinder;
	}

	private DetachedCriteria getQueryCriteria(StockTransferVo stockTransfer) {
		DetachedCriteria detachedCriteria = stockTransferDao.createCriteria();

		if (StringUtil.isExist(stockTransfer.getTransferNo())) {
			detachedCriteria.add(Restrictions.like("transferNo", stockTransfer.getTransferNo(), MatchMode.ANYWHERE));
		}
		if (ObjectUtil.isNotNull(stockTransfer.getFlowState())) {
			detachedCriteria.add(Restrictions.eq("flowState", stockTransfer.getFlowState()));
		}
		if (StringUtil.isExist(stockTransfer.getTransferInWhNo())) {
			detachedCriteria.add(Restrictions.eq("transferInWhNo", stockTransfer.getTransferInWhNo()));
		}
		if (StringUtil.isExist(stockTransfer.getTransferOutWhNo())) {
			detachedCriteria.add(Restrictions.eq("transferOutWhNo", stockTransfer.getTransferOutWhNo()));
		}
		if (StringUtil.isExist(stockTransfer.getTransferOutWhNo())) {
			detachedCriteria.add(Restrictions.eq("transferOutWhNo", stockTransfer.getTransferOutWhNo()));
		}
		if (StringUtil.isExist(stockTransfer.getTransferInWhNo())) {
			detachedCriteria.add(Restrictions.eq("transferInWhNo", stockTransfer.getTransferInWhNo()));
		}
		if (StringUtil.isExist(stockTransfer.getBeginTransferInTime())) {
			detachedCriteria.add(Restrictions.ge("transferInTime",
					DateUtil.parseTimesTampDate(stockTransfer.getBeginTransferInTime())));
		}
		if (StringUtil.isExist(stockTransfer.getEndTransferInTime())) {
			detachedCriteria.add(Restrictions.le("transferInTime",
					DateUtil.parseTimesTampDate(stockTransfer.getEndTransferInTime())));
		}
		if (StringUtil.isExist(stockTransfer.getBeginTransferOutTime())) {
			detachedCriteria.add(Restrictions.ge("transferOutTime",
					DateUtil.parseTimesTampDate(stockTransfer.getBeginTransferOutTime())));
		}
		if (StringUtil.isExist(stockTransfer.getEndTransferOutTime())) {
			detachedCriteria.add(Restrictions.le("transferOutTime",
					DateUtil.parseTimesTampDate(stockTransfer.getEndTransferOutTime())));
		}
		detachedCriteria.addOrder(Order.desc("createTime"));
		return detachedCriteria;
	}

	@Override
	@Transactional
	public boolean addStockTransfer(StockTransfer stockTransfer, List<StockTransferProduct> stockTransferProduct)
			throws Exception {
		if (ObjectUtil.isNotNull(stockTransfer) && !CollectionUtils.isEmpty(stockTransferProduct)) {
			stockTransfer.setTransferNo(NoUtil.getNo(NoUtil.STOCKTRANSFER_NO));
			stockTransfer.setFlowState(SZSCMConstant.TRANSFER_TYPE_0);
			stockTransfer.setDirector((UserUtils.getLoginUserName()));
			stockTransfer.setCreateTime(DateUtil.parseSqlDate(DateUtil.getCurrentDate()));
			stockTransferDao.save(stockTransfer);
			addStockTransferProduct(stockTransfer, stockTransferProduct);
			return true;
		}
		return false;
	}

	@Override
	@Transactional
	public boolean updateStockTransfer(StockTransfer stockTransfer, List<StockTransferProduct> stockTransferProduct)
			throws Exception {
		StockTransfer stockTransferFromDB = stockTransferDao.getById(stockTransfer.getId());
		if (ObjectUtil.isNotNull(stockTransferFromDB)
				&& stockTransferFromDB.getFlowState().equals(SZSCMConstant.TRANSFER_TYPE_0)) {
			stockTransferDao.update(stockTransfer);
			deleteTransferProductByNo(stockTransfer.getTransferNo());
			addStockTransferProduct(stockTransfer, stockTransferProduct);
			return true;
		}
		return false;
	}

	@Override
	@Transactional
	public boolean deleteStockTransfer(String id) throws Exception {
		StockTransfer stockTransferFromDB = stockTransferDao.getById(id);
		if (ObjectUtil.isNotNull(stockTransferFromDB)
				&& stockTransferFromDB.getFlowState().equals(SZSCMConstant.TRANSFER_TYPE_0)) {
			if(stockTransferDao.removeById(id)){
				deleteTransferProductByNo(stockTransferFromDB.getTransferNo());
			}
			return true;
		}
		return false;
	}

	@Override
	@Transactional
	public boolean setApproveFlowState(String transferNo) throws Exception {
		StockTransfer stockTransferFromDB = stockTransferDao.get("transferNo", transferNo);
		if (ObjectUtil.isNotNull(stockTransferFromDB) && stockTransferFromDB.getFlowState().equals(SZSCMConstant.TRANSFER_TYPE_0)) {
			stockTransferFromDB.setFlowState(SZSCMConstant.TRANSFER_TYPE_1);
			stockTransferFromDB.setAuditor((UserUtils.getLoginUserName()));
			stockTransferFromDB.setApproveTime(DateUtil.parseSqlDate(DateUtil.getCurrentDate()));
			stockTransferDao.update(stockTransferFromDB);
			return true;
		}
		return false;
	}

	@Override
	@Transactional
	public boolean setStockOutFlowState(String transferNo) throws Exception {
		StockTransfer stockTransferFromDB = stockTransferDao.get("transferNo", transferNo);
		if (ObjectUtil.isNotNull(stockTransferFromDB) && stockTransferFromDB.getFlowState().equals(SZSCMConstant.TRANSFER_TYPE_1)) {
			stockTransferFromDB.setFlowState(SZSCMConstant.TRANSFER_TYPE_2);
			stockTransferDao.update(stockTransferFromDB);
			return true;
		}
		return false;
	}
	@Override
	@Transactional
	public boolean setStockOutFinishFlowState(String transferNo) throws Exception {
		StockTransfer stockTransferFromDB = stockTransferDao.get("transferNo", transferNo);
		if (ObjectUtil.isNotNull(stockTransferFromDB) && stockTransferFromDB.getFlowState().equals(SZSCMConstant.TRANSFER_TYPE_2)) {
			stockTransferFromDB.setFlowState(SZSCMConstant.TRANSFER_TYPE_3);
			stockTransferFromDB.setTransferOutTime(DateUtil.parseSqlDate(DateUtil.getCurrentDate()));
			stockTransferDao.update(stockTransferFromDB);
			return true;
		}
		return false;
	}
	@Override
	@Transactional
	public boolean setStockInFlowState(String transferNo) throws Exception {
		StockTransfer stockTransferFromDB = stockTransferDao.get("transferNo", transferNo);
		if (ObjectUtil.isNotNull(stockTransferFromDB) && stockTransferFromDB.getFlowState().equals(SZSCMConstant.TRANSFER_TYPE_3)) {
			stockTransferFromDB.setFlowState(SZSCMConstant.TRANSFER_TYPE_4);
			stockTransferDao.update(stockTransferFromDB);
			return true;
		}
		return false;
	}
	
	@Override
	@Transactional
	public boolean setStockInFinishFlowState(String transferNo) throws Exception {
		StockTransfer stockTransferFromDB = stockTransferDao.get("transferNo", transferNo);
		if (ObjectUtil.isNotNull(stockTransferFromDB) && stockTransferFromDB.getFlowState().equals(SZSCMConstant.TRANSFER_TYPE_4)) {
			stockTransferFromDB.setFlowState(SZSCMConstant.TRANSFER_TYPE_5);
			stockTransferFromDB.setTransferInTime(DateUtil.parseSqlDate(DateUtil.getCurrentDate()));
			stockTransferDao.update(stockTransferFromDB);
			return true;
		}
		return false;
	}
	
	@Transactional
	private void addStockTransferProduct(StockTransfer stockTransfer, List<StockTransferProduct> stockTransferProducts)
			throws Exception {
		for (StockTransferProduct stockTransferProduct : stockTransferProducts) {
			stockTransferProduct.setTransferNo(stockTransfer.getTransferNo());
			stockTransferProductDao.save(stockTransferProduct);
		}
	}

	@Transactional
	private void deleteTransferProductByNo(String transferNo) throws Exception {
		stockTransferProductDao.deleteTransferProductByNo(transferNo);
	}

	@Override
	public StockTransfer getStockTransferById(String id) throws Exception {
		return stockTransferDao.getById(id);
	}
}
